// MARK 基础实现
function debounce (fn) {
  let timer
  return () => {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(fn, 1000)
  }
}

// MARK 执行环境、参数
function debounceContext (fn, context, ...args) {
  let timer
  return (...innerArgs) => {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(fn.bind(context, ...args, ...innerArgs), 1000)
  }
}

// MARK 立即执行
function debounceImmediately (fn, context, isImmediately = true, ...args) {
  let timer
  return (...innerArgs) => {
    const bindAfter = fn.bind(context, ...args, ...innerArgs)
    if (isImmediately) {
      isImmediately = false
      bindAfter()
    }
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(bindAfter, 1000)
  }
}

// MARK 取消
// 现在因为取消之后循环定时器又开启了新任务，所以看起来有问题
function debounceCancel (fn, context, isImmediately = true, ...args) {
  let timer
  return {
    cancel () {
      console.log('取消')
      if (timer) clearTimeout(timer)
    },
    debounceFn (...innerArgs) {
      const bindAfter = fn.bind(context, ...args, ...innerArgs)
      if (isImmediately) {
        isImmediately = false
        bindAfter()
      }
      if (timer) {
        clearTimeout(timer)
      }
      timer = setTimeout(bindAfter, 1000)
    }
  }
}

// MARK 返回值-通过Promise实现

const fn = function (a, b) {
  console.log(this, [a, b])
  console.log('执行')
}

const obj = { name: 'obj' }

const { debounceFn, cancel } = debounceCancel(fn, obj, true, 5, 6)

const intervalId = setInterval(debounceFn, 100)
setTimeout(() => {
  clearInterval(intervalId)
}, 3000)
